/* verilator lint_off UNUSEDSIGNAL */
`include "defines.svh"
`default_nettype wire

module WB_STAGE(
    input clk,
    input reset,
    input logic mem_valid,
    output logic wb_ready,
    input mem_to_wb_bus_t mem_to_wb_bus,
    output wb_to_id_bus_t wb_to_id_bus,
    output wb_to_dpic_bus_t wb_to_dpic_bus,

    // bypass
    output wb_to_front_bypass_t wb_to_front_bypass
);
mem_to_wb_bus_t mem_to_wb_bus_r;
word_t wb_pc,wb_inst;

// assign ecallreq_from_wb = (mem_to_wb_bus_r.sel_exception == `EXC_EC);
// assign ecallreq_pc_from_wb = wb_pc;
// assign ecallreq_inst_from_wb = wb_inst;


logic mw_shake,stall_wb,flush_wb,wb_valid;
assign mw_shake = mem_valid & wb_ready;
assign stall_wb = `OFF;
assign flush_wb = `OFF;
always_ff @(posedge clk) begin
    if(reset) begin
        wb_valid <= `OFF;
    end else begin
        wb_valid <= mw_shake;
    end
end

assign wb_ready = `ON;

// 接收
always_ff @(posedge clk) begin
    if(reset) begin
        mem_to_wb_bus_r <= `NULL;
    end else if(mw_shake & ~stall_wb & ~flush_wb) begin
        mem_to_wb_bus_r <= mem_to_wb_bus;
    end else if(flush_wb & ~stall_wb) begin
        mem_to_wb_bus_r <= `NULL;
    end
end


// 发送dpic(无阻塞)
logic debug_ebreak_en;
always_comb begin
    if(reset) begin
        debug_ebreak_en = `NULL;
        wb_to_dpic_bus = `NULL;
    end else if (flush_wb) begin
        debug_ebreak_en = `NULL;
        wb_to_dpic_bus = `NULL;
    end else begin
        debug_ebreak_en = (mem_to_wb_bus_r.sel_exception==`EXC_EB); //ebreak_en
        wb_to_dpic_bus = '{
            wb_pc,
            mem_to_wb_bus_r.debug_dnpc,
            wb_inst,

            // mem_to_wb_bus_r.debug_brjmp_en,
            mem_to_wb_bus_r.debug_load_en & wb_valid,
            mem_to_wb_bus_r.debug_store_en & wb_valid,
            mem_to_wb_bus_r.debug_ls_addr,
            debug_ebreak_en & wb_valid
        };
    end
end


// 发送gpr/csr(无阻塞)
logic [1:0] log_sel_exception;
rfcaddr_t log_rfc_waddr;
word_t log_rfc_wdata;
assign {wb_pc,wb_inst} = {mem_to_wb_bus_r.pc,mem_to_wb_bus_r.inst};
assign log_sel_exception = mem_to_wb_bus_r.sel_exception;
assign log_rfc_waddr = mem_to_wb_bus_r.rfc_waddr;
assign log_rfc_wdata = mem_to_wb_bus_r.rfc_wdata;
assign wb_to_id_bus = '{
    mem_to_wb_bus_r.rf_wen & wb_valid,
    mem_to_wb_bus_r.rf_waddr,
    mem_to_wb_bus_r.rf_wdata,

    (mem_to_wb_bus_r.sel_exception == `EXC_ON) & wb_valid,
    mem_to_wb_bus_r.rfc_waddr,
    mem_to_wb_bus_r.rfc_wdata
};

assign wb_to_front_bypass.ecall_en = (mem_to_wb_bus_r.sel_exception == `EXC_EC);
assign wb_to_front_bypass.wb_ecall_pc = wb_pc;
assign wb_to_front_bypass.wb_ecall_inst = wb_inst;

endmodule
